package com.youchuang.dao.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Repository;

import com.youchuang.bean.Book;
import com.youchuang.bean.Product;
import com.youchuang.common.HibernateConnection;
import com.youchuang.dao.BookDAO;

@Repository("BookDAO")
public class BookDAOImpl implements BookDAO {

	private static final String HQL_FIND_ALL = "from Book b join Product p with b.id = p.id where p.hasDeleted = 0";
	private static final String HQL_FIND_BY_CAT_ID = "from Book b join Product p with b.id = p.id join CategoryProduct c with b.id = c.productId where p.hasDeleted = 0 and c.categoryId = :categoryId ";
	private static final String HQL_FIND_BY_ID = "from Book b join Product p with b.id = p.id where p.hasDeleted = 0 and b.id = :id";
	private static final String HQL_FIND_BY_HOT = "FROM IndentItem i JOIN Product p with i.productId=p.id JOIN Book b with i.productId=b.id WHERE p.hasDeleted=0 GROUP BY productId ORDER BY COUNT(i.productId) DESC";
	private static final String HQL_FIND_BY_NEW = "FROM Product p JOIN Book b with p.id=b.id WHERE p.hasDeleted=0 ORDER BY p.addTime DESC";
	private static final String HQL_FIND_BY_HOT_NEW = "FROM IndentItem i JOIN Product p with i.productId=p.id JOIN Book b with i.productId=b.id WHERE p.hasDeleted=0 AND p.addTime>:addTime GROUP BY productId ORDER BY COUNT(i.productId) desc";
	private static final String HQL_FIND_ALL_COUNT = "SELECT COUNT(p.id) FROM Book b join Product p with b.id = p.id WHERE p.hasDeleted= 0";
	private static final String HQL_FIND_LIKE_BY_PRODUCTNAME = "FROM Product p JOIN Book b ON p.id = b.id WHERE p.hasDeleted = 0 AND p.productName LIKE :name";
	private static final String HQL_FIND_BY_CATEGORYID_NEW = "FROM CategoryProduct c JOIN Product p ON c.productId=p.id JOIN Book b with b.id=p.id WHERE p.hasDeleted=0 AND c.categoryId= :categoryId ORDER BY p.addTime DESC";
	private static final String HQL_FIND_BY_CATEGORYID_HOT = "FROM CategoryProduct c JOIN Product p with c.productId=p.id JOIN Book b with p.id=b.id JOIN IndentItem i with i.productId=p.id WHERE p.hasDeleted=0 AND c.categoryId=:categoryId GROUP BY c.productId ORDER BY COUNT(c.productId) DESC";

	@Resource
	private HibernateConnection<Book> hibernateConnection;

	/**
	 * 重新组合book实体
	 * 
	 * @param iterator
	 * @param books
	 */
	@SuppressWarnings("rawtypes")
	private void assembleBooks(Iterator iterator, List<Book> books) {
		while (iterator.hasNext()) {
			Object[] objects = (Object[]) iterator.next();
			Book book = null;
			Product product = null;
			for (Object object : objects) {
				if (object instanceof Book) {
					book = (Book) object;
				} else if (object instanceof Product) {
					product = (Product) object;
				}
			}
			if (book != null) {
				book.setProduct(product);
				books.add(book);
			}
		}
	}

	@Override
	public void save(Book t) {
		hibernateConnection.save(t);
	}

	@Override
	public void delete(Book t) {
		// Do nothing because of it unusual
	}

	@Override
	public int update(Book t) {
		// Do nothing because of it unusual
		return 0;
	}

	@Override
	public List<Book> queryAll() {
		List<Book> list = hibernateConnection.find(HQL_FIND_ALL);
		return list;
	}

	@SuppressWarnings("rawtypes")
	@Override
	public List<Book> queryLimmitByCategoryId(String categoryId, int first, int max) {
		Map<String, Object> params = new HashMap<>();
		params.put("categoryId", categoryId);
		Iterator iterator = hibernateConnection.findGetIterator(HQL_FIND_BY_CAT_ID, params, first, max);

		List<Book> books = new ArrayList<>();
		assembleBooks(iterator, books);
		return books;
	}

	@SuppressWarnings("rawtypes")
	@Override
	public Book queryById(String id) {
		Map<String, Object> params = new HashMap<>();
		params.put("id", id);
		Iterator iterator = hibernateConnection.findGetIterator(HQL_FIND_BY_ID, params);

		List<Book> books = new ArrayList<>();
		assembleBooks(iterator, books);

		if (CollectionUtils.isEmpty(books)) {
			return null;
		}
		return books.get(0);
	}

	@SuppressWarnings("rawtypes")
	@Override
	public List<Book> queryLimmitByHot(int first, int max) {
		Iterator iterator = hibernateConnection.findGetIterator(HQL_FIND_BY_HOT, first, max);
		List<Book> books = new ArrayList<>();
		assembleBooks(iterator, books);
		return books;
	}

	@SuppressWarnings("rawtypes")
	@Override
	public List<Book> queryLimmitByNew(int first, int max) {
		Iterator iterator = hibernateConnection.findGetIterator(HQL_FIND_BY_NEW, first, max);
		List<Book> books = new ArrayList<>();
		assembleBooks(iterator, books);
		return books;
	}

	@SuppressWarnings("rawtypes")
	@Override
	public List<Book> queryLimmitByHotNew(long addTime, int first, int max) {
		Map<String, Object> params = new HashMap<>();
		params.put("addTime", addTime);
		Iterator iterator = hibernateConnection.findGetIterator(HQL_FIND_BY_HOT_NEW, params, first, max);
		List<Book> books = new ArrayList<>();
		assembleBooks(iterator, books);
		return books;
	}

	@Override
	public int queryAllCount() {
		return hibernateConnection.count(HQL_FIND_ALL_COUNT).intValue();
	}

	@SuppressWarnings("rawtypes")
	@Override
	public List<Book> queryLimmitLikeByPruductName(String productName, int first, int max) {
		Map<String, Object> params = new HashMap<>();
		params.put("name", productName);
		Iterator iterator = hibernateConnection.findGetIterator(HQL_FIND_LIKE_BY_PRODUCTNAME, params, first, max);
		List<Book> books = new ArrayList<>();
		assembleBooks(iterator, books);
		return books;
	}

	@SuppressWarnings("rawtypes")
	@Override
	public List<Book> queryLimmitByCategoryIdNew(String categoryId, int first, int max) {
		Map<String, Object> params = new HashMap<>();
		params.put("categoryId", categoryId);
		Iterator iterator = hibernateConnection.findGetIterator(HQL_FIND_BY_CATEGORYID_NEW, params, first, max);
		List<Book> books = new ArrayList<>();
		assembleBooks(iterator, books);
		return books;
	}

	@SuppressWarnings("rawtypes")
	@Override
	public List<Book> queryLimmitByCategoryIdHot(String categoryId, int first, int max) {
		Map<String, Object> params = new HashMap<>();
		params.put("categoryId", categoryId);
		Iterator iterator = hibernateConnection.findGetIterator(HQL_FIND_BY_CATEGORYID_HOT, params, first, max);
		List<Book> books = new ArrayList<>();
		assembleBooks(iterator, books);
		return books;
	}

}
